package com.lm.statemachine.service;

import com.lm.statemachine.entry.Order;
import com.lm.statemachine.enums.OrderEvent;
import com.lm.statemachine.enums.OrderState;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.messaging.Message;
import org.springframework.messaging.support.MessageBuilder;
import org.springframework.statemachine.StateMachine;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.Objects;

@Service
public class OrderService{
    private static final Logger log = LoggerFactory.getLogger(OrderService.class);

    @Resource
    private StateMachine<OrderState, OrderEvent> stateMachine;

    public void payOrder(Integer id) {
        log.info("Pay Order: {}", id);
        Order order = new Order();
        order.setId(12321l);
        order.setOrderNo("qasfqwerwerwqerqwe");
        order.setProductName("袜子");
        order.setAmount(new BigDecimal("100.00"));
        order.setState(OrderState.CREATED);
        //TODO 模拟支付
        Message<OrderEvent> message = MessageBuilder.withPayload(OrderEvent.PAY).setHeader("order", order).build();

        if (!sendEvent(message)) {
            System.out.println(" deliver created，error，order no：" + id);
        }
    }

    public void shipOrder(Integer id) {
        log.info("Ship Order: {}", id);
        Order order = new Order();
        order.setId(12334l);
        order.setOrderNo("qasfqwerwerADSFAS");
        order.setProductName("鞋子");
        order.setAmount(new BigDecimal("99.99"));
        order.setState(OrderState.PAID);
        // TODO 模拟发货
        Message<OrderEvent> message = MessageBuilder.withPayload(OrderEvent.SHIP).setHeader("order", order).build();
        if (!sendEvent(message)) {
            System.out.println(" deliver PAID，error，order no：" + id);
        }
    }

    public void completeOrder(Integer id) {
        log.info("Complete Order: {}", id);
        Order order = new Order();
        order.setId(12345l);
        order.setOrderNo("qasfqwerwerADFADSFA");
        order.setProductName("鞋子");
        order.setAmount(new BigDecimal("99.99"));
        order.setState(OrderState.SHIPPED);
        Message<OrderEvent> message = MessageBuilder.withPayload(OrderEvent.COMPLETE).setHeader("order", order).build();
        if (!sendEvent(message)) {
            System.out.println(" deliver SHIPPED，error，order no：" + id);
        }
    }

    private synchronized boolean sendEvent(Message<OrderEvent> message) {
        boolean result = false;
        try {
            stateMachine.start();
            result = stateMachine.sendEvent(message);
        } catch (Exception e) {
            log.error(e.getMessage());
        } finally {
            if (Objects.nonNull(message)) {
                Order order = (Order) message.getHeaders().get("order");
                if (Objects.nonNull(order) && Objects.equals(order.getState(), OrderState.COMPLETED)) {
                    stateMachine.stop();
                }
            }
        }
        return result;
    }

}
